#ifndef RINGBUF16_H
#define RINGBUF16_H

#include "sys.h"

#ifdef __cplusplus
extern "C" {
#endif

/**
 * \brief      Structure that holds the state of a ring buffer.
 *
 *             This structure holds the state of a ring buffer. The
 *             actual buffer needs to be defined separately. This
 *             struct is an opaque structure with no user-visible
 *             elements.
 *
 */
struct ringbuf
{
    uint8_t *data;
    uint16_t mask;

    /* XXX these must be 8-bit quantities to avoid race conditions. */
    uint16_t put_ptr, get_ptr;
};

typedef struct ringbuf Ringbuf16_ST;


//soso
void Ringbuf16_Reset(Ringbuf16_ST *r);
/**
 * \brief      Initialize a ring buffer
 * \param r    A pointer to a Ringbuf16_ST to hold the state of the ring buffer
 * \param a    A pointer to an array to hold the data in the buffer
 * \param size_power_of_two The size of the ring buffer, which must be a power of two
 *
 *             This function initiates a ring buffer. The data in the
 *             buffer is stored in an external array, to which a
 *             pointer must be supplied. The size of the ring buffer
 *             must be a power of two and cannot be larger than 128
 *             bytes.
 *
 */
void    Ringbuf16_Init(Ringbuf16_ST *r, uint8_t *a,
                     uint16_t size_power_of_two);

/**
 * \brief      Insert a byte into the ring buffer
 * \param r    A pointer to a Ringbuf16_ST to hold the state of the ring buffer
 * \param c    The byte to be written to the buffer
 * \return     Non-zero if there data could be written, or zero if the buffer was full.
 *
 *             This function inserts a byte into the ring buffer. It
 *             is safe to call this function from an interrupt
 *             handler.
 *
 */
int32_t     Ringbuf16_Put(Ringbuf16_ST *r, uint8_t c);


/**
 * \brief      Get a byte from the ring buffer
 * \param r    A pointer to a Ringbuf16_ST to hold the state of the ring buffer
 * \return     The data from the buffer, or -1 if the buffer was empty
 *
 *             This function removes a byte from the ring buffer. It
 *             is safe to call this function from an interrupt
 *             handler.
 *
 */
int32_t     Ringbuf16_Get(Ringbuf16_ST *r);

/**
 * \brief      Insert a byte into the ring buffer
 * \param r    A pointer to a Ringbuf16_ST to hold the state of the ring buffer
 * \param c    The byte to be written to the buffer
 * \return     Non-zero if there data could be written, or zero if the buffer was full.
 *
 *             This function inserts a byte into the ring buffer. It
 *             is safe to call this function from an interrupt
 *             handler.
 *
 */
int32_t
Ringbuf16_PutArray(struct ringbuf *r, const uint8_t array[], int32_t size);

/**
 * \brief      Get a byte from the ring buffer
 * \param r    A pointer to a Ringbuf16_ST to hold the state of the ring buffer
 * \return     The data from the buffer, or -1 if the buffer was empty
 *
 *             This function removes a byte from the ring buffer. It
 *             is safe to call this function from an interrupt
 *             handler.
 *
 */
int32_t
Ringbuf16_GetArray(struct ringbuf *r, uint8_t array[], int32_t length);

/**
 * \brief      Get the size of a ring buffer
 * \param r    A pointer to a Ringbuf16_ST to hold the state of the ring buffer
 * \return     The size of the buffer.
 */
int32_t     Ringbuf16_Size(Ringbuf16_ST *r);

/**
 * \brief      Get the number of elements currently in the ring buffer
 * \param r    A pointer to a Ringbuf16_ST to hold the state of the ring buffer
 * \return     The number of elements in the buffer.
 */
int32_t Ringbuf16_Elements(Ringbuf16_ST *r);

/**
 * \brief      Get the pointer of wriiting bites in the ring buffer
 * \param r    A pointer to a Ringbuf16_ST to hold the state of the ring buffer
 * \return     The pointer of writting bites in the buffer.
 */
uint8_t * Ringbuf16_GetPutPtr(struct ringbuf *r);

/**
 * \brief      Get the length of the rest bites that could be written currently in the ring buffer
 * \param r    A pointer to a Ringbuf16_ST to hold the state of the ring buffer
 * \param isContinuous   Judge whether the bite is written once or one by one
 * \return     The length of bites that could be written in the buffer.
 */
int32_t Ringbuf16_GetPutLength(struct ringbuf *r, int32_t isContinuous);

/**
 * \brief      Increase the pointer of writting bites in the ring buffer
 * \param r    A pointer to a Ringbuf16_ST to hold the state of the ring buffer
 * \param size The size of number to be increased
 * \return     The pointer of writting bites after being increased  in the buffer.
 */
void Ringbuf16_PutPtrInc(struct ringbuf *r, int32_t size);

/**
 * \brief      Get the pointer of getting bites in the ring buffer
 * \param r    A pointer to a Ringbuf16_ST to hold the state of the ring buffer
 * \return     The pointer of getting bites in the buffer.
 */
uint8_t * Ringbuf16_GetGetPtr(struct ringbuf *r);

/**
 * \brief      Get the length of the rest bites that could be gotten currently in the ring buffer
 * \param r    A pointer to a Ringbuf16_ST to hold the state of the ring buffer
 * \param isContinuous   Judge whether the bites are gotten once or one by one
 * \return     The length of bites that could be gotten in the buffer.
 */
int32_t Ringbuf16_GetGetLength(struct ringbuf *r, int32_t isContinuous);

/**
 * \brief      Increase the pointer of getting bites in the ring buffer
 * \param r    A pointer to a Ringbuf16_ST to hold the state of the ring buffer
 * \param size The size of number to be increased
 * \return     The pointer of getting bites after being increased in the buffer.
 */
void Ringbuf16_GetPtrInc(struct ringbuf *r, int32_t size);

#ifdef __cplusplus
}
#endif

#endif /* RINGBUF16_H_ */

/** @}*/
/** @}*/
